import 'dart:async';
import 'dart:convert';
import 'dart:ui';

import 'package:audioplayers/audio_cache.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:logger/logger.dart';
import 'package:overlay_support/overlay_support.dart';
import 'package:qgchat/common/global/global.dart';
import 'package:qgchat/http/models/tokenuserInfoModel.dart';
import 'package:qgchat/widgets/Zego/ZegoPreview.dart';
import 'package:zego_express_engine/zego_express_engine.dart';

import 'Bloc/TargetInfoBloc.dart';

class LodingCall extends StatefulWidget {
  final String targetToken;
  LodingCall({@required this.targetToken, Key key}) : super(key: key);

  @override
  _LodingCallState createState() => _LodingCallState();
}

class _LodingCallState extends State<LodingCall> {
  final zegoKey = GlobalKey<ZegoPreviewState>();
  StreamSubscription stopCallSub;
  StreamSubscription invtokenSub;
  Timer timer;

  @override
  void initState() {
    super.initState();
    final not = Global.socketNot;

    // 修改通话状态
    Global.talking.value = true;
    // 发起视频邀请
    Global.ws.inviteVideo(widget.targetToken);

    // 30s内未接听挂断电话
    timer = Timer(
      Duration(seconds: 30),
      () {
        if (mounted) {
          toast('长时间未接听，自动挂断');
          Navigator.pop(context);
        }
      },
    );

    // socket - 对方停止拨号监听
    stopCallSub = not.value
        .map((str) => jsonDecode(str))
        .where((cls) => cls['datatype'] == 'uninvtoken')
        .listen(
      (res) {
        toast('对方拒绝了视频邀请');
        Navigator.pop(context);
      },
    );

    // socket - 对方接受了视频邀请
    invtokenSub = not.value
        .map((str) => jsonDecode(str))
        .where((cls) => cls['datatype'] == 'invtokening')
        .map((map) => map['data']['inv'])
        .listen(
      (inv) {
        if (!Global.talking.value) return;

        zegoKey.currentState.isDispose = false;
        final textureID = zegoKey.currentState.info.textureID;
        ZegoExpressEngine.instance.stopPreview().then((value) {
          ZegoExpressEngine.instance
              .destroyTextureRenderer(textureID)
              .then((value) {
            // 进入通话页面
            goPage(
              context,
              '/talk',
              param: {
                'inv': inv,
                'token': widget.targetToken,
              },
              replace: true,
            );
          });
        });
      },
    );
  }

  @override
  void dispose() {
    timer?.cancel();
    stopCallSub?.cancel();
    invtokenSub?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return BlocProvider<TargetInfoBlocBloc>(
      create: (context) => TargetInfoBlocBloc(
        targetToken: widget.targetToken,
      ),
      child: WillPopScope(
        onWillPop: () async => false,
        child: _Ringtone(
          child: Scaffold(
            backgroundColor: Colors.grey,
            body: Stack(
              alignment: Alignment.center,
              children: [
                Builder(
                  builder: (context) {
                    // 计算屏幕像素
                    final width = MediaQuery.of(context).size.width.toInt();
                    final height = MediaQuery.of(context).size.height.toInt();
                    final ratio =
                        MediaQuery.of(context).devicePixelRatio.toInt();
                    final screenWidthPx = width * ratio;
                    final screenHeightPx = height * ratio;
                    return ZegoPreview(
                      screenWidthPx: screenWidthPx,
                      screenHeightPx: screenHeightPx,
                      key: zegoKey,
                    );
                  },
                ),
                _FilterBlur(),
                _UserInfo(),
                _TipsText(),
                _ToolPanel(zegoKey: zegoKey),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// 铃声播放
class _Ringtone extends StatefulWidget {
  final Widget child;
  _Ringtone({@required this.child, Key key}) : super(key: key);

  @override
  __RingtoneState createState() => __RingtoneState();
}

class __RingtoneState extends State<_Ringtone> {
  AudioCache audio;
  AudioPlayer player;

  @override
  void initState() {
    super.initState();
    audio = AudioCache(prefix: 'audio/');
    audio.loop("callOther.mp3").then((value) => player = value);
  }

  @override
  void dispose() {
    player?.stop();
    audio?.clear("callOther.mp3");
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => widget.child;
}

// 毛玻璃层
class _FilterBlur extends StatelessWidget {
  const _FilterBlur({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BackdropFilter(
      filter: ImageFilter.blur(sigmaX: 30, sigmaY: 30),
      child: Container(
        color: Colors.white.withAlpha(0),
      ),
    );
  }
}

// 用户信息
class _UserInfo extends StatelessWidget {
  const _UserInfo({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final top = MediaQuery.of(context).padding.top;
    return BlocBuilder<TargetInfoBlocBloc, TokenuserInfoModel>(
      builder: (context, state) {
        if (state.id == null) return Container();

        return Positioned(
          top: top + px(128),
          child: Column(
            children: [
              Container(
                width: px(180),
                height: px(180),
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(90),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black12,
                      offset: Offset(0.0, 1),
                      blurRadius: 1,
                      spreadRadius: 1,
                    ),
                  ],
                  image: DecorationImage(
                    fit: BoxFit.cover,
                    image: NetworkImage(
                      state.memberHead,
                    ),
                  ),
                ),
              ),
              SizedBox(height: px(40)),
              Text(
                state.memberNickname,
                style: TextStyle(
                  color: Colors.white,
                  fontSize: px(38),
                  shadows: [
                    Shadow(
                      color: Colors.black26,
                      blurRadius: 1,
                      offset: Offset(1, 1),
                    ),
                  ],
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}

// 提示
class _TipsText extends StatelessWidget {
  const _TipsText({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Positioned(
      bottom: px(400),
      child: Text(
        '正在等待对方接听...',
        style: TextStyle(
          color: Colors.white,
          fontSize: px(26),
          shadows: [
            Shadow(
              color: Colors.black26,
              blurRadius: 1,
              offset: Offset(1, 1),
            ),
          ],
        ),
      ),
    );
  }
}

// 操作按钮
class _ToolPanel extends StatelessWidget {
  final GlobalKey<ZegoPreviewState> zegoKey;
  const _ToolPanel({this.zegoKey, Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Positioned(
      bottom: px(50),
      child: Container(
        width: w100(context),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            GestureDetector(
              onTap: () {
                final token = context.bloc<TargetInfoBlocBloc>().targetToken;
                Global.ws.stopinv(token);
                Navigator.of(context).pop();
                Global.talking.value = false;
              },
              child: _ToolPanelItem(
                icon: 'oncall',
                title: '挂断',
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// 操作按钮单元
class _ToolPanelItem extends StatelessWidget {
  final String icon;
  final String title;
  const _ToolPanelItem({
    @required this.icon,
    @required this.title,
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: <Widget>[
        Container(
          width: px(150),
          height: px(150),
          child: Image.asset(
            "assets/images/icon/$icon.png",
            fit: BoxFit.cover,
          ),
        ),
        SizedBox(height: px(16)),
        Text(
          title,
          style: TextStyle(
            color: Colors.white,
            fontSize: px(32),
            shadows: [
              Shadow(
                color: Colors.black26,
                blurRadius: 1,
                offset: Offset(1, 1),
              ),
            ],
          ),
        ),
      ],
    );
  }
}
